<script lang="ts" setup>
import { handleStream, sendMessage, type IOnData, type IOnError } from '@/api'
import { useUserStore } from '@/stores/user'
import { RecordRole, ResponseMode, type RecordItem } from '@/types'
import { computed, onMounted, ref } from 'vue'

import hljs from 'highlight.js'
import MarkdownIt from 'markdown-it'
import 'highlight.js/styles/atom-one-dark.css'
import { useConversationStore } from '@/stores/conversation'
import { useToast } from 'vue-toastification'

const props = defineProps<{
  item: RecordItem
}>()

const emit = defineEmits<{
  answerUpdate: []
}>()

const toast = useToast()
const userStore = useUserStore()
const conversationStore = useConversationStore()

const answer = ref('')
const error = ref('')
const isAnswering = ref(false)

const answerList = computed(() => {
  const answerText = answer.value || props.item.answer || ''
  if (answerText.indexOf('<details') === -1) {
    return [undefined, answerText]
  }
  return answerText.split('<details>')
  // const list = (answer.value || props.item.answer || '').split('</details>')
  // if (list.length === 1) {
  //   return [undefined, list[0]]
  // }
  // return list
})

// watch(answerList, (newVal) => {
//   console.log('answerList', newVal)
// })

const thinkingText = computed(() => {
  return answerList.value[0] || ''
})

const mdText = computed(() => {
  return answerList.value[1] || ''
})

const md: MarkdownIt = MarkdownIt({
  highlight: (str: string, lang: string) => {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<div class="hljs rounded-md !my-2 !p-4 overflow-x-auto"><div>[<i>${lang}</i>]</div><div><code>${hljs.highlight(lang, str).value}</code></div></div>`
      } catch (e) {
        console.error(e)
      }
    }
    return ''
  },
})

onMounted(() => {
  if (props.item.role === RecordRole.assistant && props.item.query && !props.item.id) {
    loadData()
  }
})

const handleOnData: IOnData = (message, isFirstMessage, moreInfo) => {
  if (isFirstMessage) {
    conversationStore.isAnswering = true
    isAnswering.value = true
  }
  answer.value += message
  emit('answerUpdate')
  if (!conversationStore.getCurrent?.id) {
    conversationStore.setConversationId(moreInfo.conversationId as string)
    conversationStore.renameConversation(conversationStore.currentKey, props.item.query as string)
  }
}

const handleOnCompleted = () => {
  conversationStore.isAnswering = false
  isAnswering.value = false
}

const handleOnThought = () => {}

const handleOnMessageEnd = () => {}

const handleOnMessageReplace = () => {}

const handleOnFile = () => {}

const handleOnWorkflowStarted = () => {}

const handleOnWorkflowFinished = () => {}

const handleOnNodeStart = () => {}

const handleOnNodeFinished = () => {}

const handleOnError: IOnError = (msg) => {
  error.value = msg
  toast.error(msg)
}

const loadData = async () => {
  const response = await sendMessage({
    query: props.item.query as string,
    response_mode: ResponseMode.streaming,
    user: userStore.userName,
    files: [],
    inputs: conversationStore.getCurrent?.inputs || {},
    auto_generate_name: false,
    conversation_id: conversationStore.getCurrent?.id,
  })
  // 处理事件
  try {
    handleStream(
      response,
      handleOnData,
      handleOnCompleted,
      handleOnThought,
      handleOnMessageEnd,
      handleOnMessageReplace,
      handleOnFile,
      handleOnWorkflowStarted,
      handleOnWorkflowFinished,
      handleOnNodeStart,
      handleOnNodeFinished,
      handleOnError,
    )
  } catch (error) {
    toast.error(error as string)
  }
}
</script>

<template>
  <div class="record-item !flex" :class="{ 'flex-row-reverse': item.role === RecordRole.user }">
    <v-avatar :color="item.role === RecordRole.user ? 'info' : 'blue-grey'">
      <v-icon :icon="item.role === RecordRole.user ? 'mdi-account-circle' : 'mdi-robot'" />
    </v-avatar>
    <v-card
      class="!mt-4 max-w-[80%]"
      :class="`${item.role === RecordRole.user ? 'mr-4 !rounded-tr-none !rounded-tl-2xl !rounded-br-2xl !rounded-bl-2xl' : 'ml-4 !rounded-tl-none !rounded-tr-2xl !rounded-bl-2xl !rounded-br-2xl'}`"
      :color="item.role === RecordRole.user ? 'info' : 'blue-grey'"
    >
      <v-card-text>
        <template v-if="item.role === RecordRole.user">
          {{ item.query }}
        </template>
        <template v-else>
          <template v-if="error || item.status === 'error'">
            <v-alert :text="error || item.error" type="warning" density="compact"></v-alert>
          </template>
          <template v-else>
            <div v-if="thinkingText" v-html="thinkingText"></div>
            <div v-if="mdText" :class="{ 'mt-2': thinkingText }" v-html="md.render(mdText)"></div>
            <div v-else-if="isAnswering" :class="{ 'mt-2': thinkingText }">
              <v-progress-circular color="primary" indeterminate></v-progress-circular>
            </div>
          </template>
        </template>
      </v-card-text>
    </v-card>
  </div>
</template>
